<template>
  <div class="scoring-module">
    <!--
    <div class="header">
      <div class="title">个人飞行赛-选手计分页面</div>
      <img class="ico-logo" src="@/assets/logo-fii.png" />
    </div>
    -->
    <div class="content">
      <div class="flying-race-box">
        <div class="flying-race-logo-wrap">
          <img class="flying-race-logo" src="@/assets/images/logo-race.png" />
        </div>
        <div class="flying-race-info">
          <!--<div class="flying-race-title">{{ contestInfo.matchName || '' }}</div>-->
          <!--
          <div class="flying-race-labels">
            <div class="flying-race-label">科目：{{ contestInfo.matchItemName || '-' }}</div>
          </div>
          -->
          <div class="flying-race-tags">
            <div class="flying-race-tag">{{ contestInfo.matchItemName || "-" }}</div>
            <div class="flying-race-tag">{{ contestInfo.userName || "-" }}</div>
            <div class="flying-race-tag">{{ queryForm.id || "-" }}</div>
            <div class="flying-race-tag">{{ contestInfo.company || "-" }}</div>
          </div>
        </div>
      </div>

      <div class="form-query-box">
        <div class="form-box">
          <div class="form-item">
            <span class="form-item-label">学员ID：</span>
            <el-input class="form-item-val" v-model="queryForm.id" placeholder="请输入学员ID"></el-input>
          </div>
          <div class="form-item">
            <span class="form-label">比赛场地：</span>
            <el-input class="form-item-val" v-model="queryForm.site" placeholder="请输入场地"></el-input>
          </div>
          <el-button class="btn-query" @click="handleQuery" type="primary">查询</el-button>
          <el-button class="btn-reset" @click="handleReset" type="default">重置</el-button>
        </div>
        <div class="scoring-box">
          <el-button class="btn-scoring" @click="handleScoring" type="primary">计分</el-button>
          <div class="scoring-count">{{ currScore || 0 }}</div>
          <div class="scoring-unit">分</div>
        </div>
      </div>

      <div class="scoring-table-box">
        <div class="scoring-table-title">得分项</div>
        <div class="scoring-table-wrap">
          <el-table class="scoring-table" :data="scoringData" :header-cell-style="{ background: '#F5F7FA', color: '#333' }">
            <el-table-column :prop="scoringItem.prop" :label="scoringItem.label" :align="scoringItem.align" v-for="(scoringItem, scoringIdx) in scoringColumn" :key="scoringIdx">
              <template #default="scope">
                <el-select v-if="scoringItem.prop === 'parkingApron'" v-model="scope.row[scoringItem.prop]" class="scoring-select" placeholder="请选择">
                  <el-option :value="scoringScore.value" :label="scoringScore.label" v-for="(scoringScore, scoringScoreIdx) in parkingApronOpts" :key="scoringScoreIdx"></el-option>
                </el-select>
                <el-radio-group v-else v-model="scope.row[scoringItem.prop]" class="scoring-radio">
                  <el-radio :value="true">是</el-radio>
                  <el-radio :value="false">否</el-radio>
                </el-radio-group>
              </template>
            </el-table-column>
          </el-table>

          <div class="scoring-time-box">
            <div class="time-label-wrap">
              <div class="time-label">时间</div>
              <div class="time-count">{{ currSeconds || "0" }}</div>
            </div>
            <div class="timer-box">
              <el-input v-model.number="secondsItem.minute" class="timer-item-ipt" type="number" :min="0"></el-input>
              <div class="timer-split">:</div>
              <el-input v-model.number="secondsItem.second" class="timer-item-ipt" type="number" :min="0"></el-input>
              <div class="timer-split">:</div>
              <el-input v-model="secondsItem.millisecond" class="timer-item-ipt" :min="0" :max="999"></el-input>
            </div>
          </div>
        </div>
      </div>

      <div class="scoring-table-box">
        <div class="scoring-table-title">扣分项</div>
        <div class="scoring-table-wrap">
          <el-table class="scoring-table" :data="deductionData" :span-method="deductionSpanMethod" :row-class-name="deductionRowClass" :header-cell-style="{ background: '#F5F7FA', color: '#333' }">
            <el-table-column :prop="deductionItem.prop" :label="deductionItem.label" :align="deductionItem.align" :width="deductionItem.width" v-for="(deductionItem, deductionIdx) in deductionColumn" :key="deductionIdx">
              <template #default="scope">
                <div v-if="scope.row.isGameOver">比赛结束</div>
                <el-radio-group v-else-if="deductionItem.prop === 'goggles'" v-model="scope.row[deductionItem.prop]" class="scoring-radio">
                  <el-radio :value="true">佩戴</el-radio>
                  <el-radio :value="false">未佩戴</el-radio>
                </el-radio-group>
                <el-input v-else v-model.number="scope.row[deductionItem.prop]" class="scoring-ipt" :class="isGameOver ? 'scoring-ipt-wran' : ''" type="number" :min="0" placeholder="请输入"></el-input>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>

      <div class="form-btns-box">
        <el-button class="form-btn btn-cancel" @click="handleCancel" type="default">取消</el-button>
        <el-button class="form-btn btn-set-full" @click="handleSetFull" type="primary">一键满分</el-button>
        <el-button class="form-btn btn-set-zero" @click="handleSetZero" type="primary">一键0分</el-button>
        <el-button class="form-btn btn-submit" @click="handleSubmit" type="primary">提交</el-button>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { reactive, ref, watch, onMounted } from "vue";
import { ElMessage } from "element-plus";
import baseService from "@/service/baseService";
import { useRoute } from "vue-router";

const contestInfo = ref({
  id: "",
  company: "",
  matchItemName: "",
  matchItemTeamId: "",
  matchName: "",
  userId: "",
  userName: ""
});
const userInfo = ref({
  name: "",
  code: "",
  school: ""
});

const queryForm = reactive({
  id: "",
  site: ""
});

const currScore = ref(0);
const maxSeconds = 120;
const defaultSeconds = `${maxSeconds}″00`;
const currSeconds = ref(defaultSeconds);
const secondsItem = ref({
  minute: 2,
  second: 0,
  millisecond: 0
});
const isScoring = ref(false);
const isGameOver = ref(false);

const scoringColumn = [
  {
    prop: "throughHoops",
    label: "钻圈(10分)",
    score: 10,
    align: "center"
  },
  {
    prop: "anticlockwise",
    label: "逆时针(10分)",
    score: 10,
    align: "center"
  },
  {
    prop: "aroundDragonGate",
    label: "绕龙门(20分)",
    score: 20,
    align: "center"
  },
  {
    prop: "highAndLowCircles",
    label: "高低圈(30分)",
    score: 30,
    align: "center"
  },
  {
    prop: "serpentineRing",
    label: "蛇形圈(30分)",
    score: 30,
    align: "center"
  },
  {
    prop: "parkingApron",
    label: "停机坪",
    score: 0,
    align: "center"
  }
];
const scoringColumnMap = ref(new Map<string, number>([]));
const scoringData = ref([
  {
    throughHoops: null,
    anticlockwise: null,
    aroundDragonGate: null,
    highAndLowCircles: null,
    serpentineRing: null,
    parkingApron: null
  }
]);
const parkingApronOpts = ref<{ label: string; value: number }[]>([]);

const deductionColumn = [
  {
    prop: "goggles",
    label: "护目镜",
    score: 0,
    align: "center",
    width: 164
  },
  {
    prop: "touchNet",
    label: "触网(5分/次)",
    score: 5,
    align: "center"
  },
  {
    prop: "touchPeople",
    label: "碰人(20分/次)",
    score: 20,
    align: "center"
  },
  {
    prop: "touchdown",
    label: "触地(20分/次)",
    score: 20,
    align: "center"
  },
  {
    prop: "obstacles",
    label: "障碍倒地(10分/次)",
    score: 10,
    align: "center",
    width: 140
  },
  {
    prop: "superelevation",
    label: "超高(10分/次)",
    score: 10,
    align: "center"
  },
  {
    prop: "cross",
    label: "出活动区(5分/次)",
    score: 5,
    align: "center",
    width: 140
  }
];
const deductionColumnMap = ref(new Map<string, number>([]));
const deductionData = ref([
  {
    isGameOver: null,
    goggles: true,
    touchNet: 0,
    touchPeople: 0,
    touchdown: 0,
    obstacles: 0,
    superelevation: 0,
    cross: 0
  }
]);

watch(
  isGameOver,
  (newVal, oldVal) => {
    if (newVal == oldVal) return;
    if (newVal && !deductionData.value.some((b) => b.isGameOver)) {
      deductionData.value.unshift({ isGameOver: true } as any);
    } else if (!newVal && deductionData.value.some((b) => b.isGameOver)) {
      deductionData.value.shift();
    }
  },
  { immediate: true }
);

onMounted(() => {
  const route = useRoute();
  const id = route.query.id as string;
  queryForm.id = id;
  handleQuery();

  contestInfo.value = {
    id: "",
    company: "衢州市白云学校",
    matchItemName: "个人空中射击赛",
    matchItemTeamId: "11865",
    matchName: "第八届全国青少年无人机大赛（浙江省赛）",
    userId: "36475",
    userName: "叶舜"
  };

  userInfo.value = {
    name: "选手 6",
    code: "苏A0102",
    school: "上海第一实验中学"
  };

  parkingApronOpts.value = [
    { label: "20", value: 20 },
    { label: "30", value: 30 },
    { label: "40", value: 40 },
    { label: "50", value: 50 }
  ];

  scoringColumnMap.value = getScoringColumnMap();
  deductionColumnMap.value = getDeductionColumnMap();
});

const handleQuery = () => {
  // todo 查询
  console.log(queryForm);
  baseService.get("/front/spuser/queryUserByTeamUserId", { id: queryForm.id }).then((res) => {
    if (res.code === 0) {
      contestInfo.value = res.data;
    }
  });
};

const handleReset = () => {
  queryForm.id = "";
  queryForm.site = "";
  handleQuery();
};

const handleScoring = () => {
  isScoring.value = true;
  if (deductionData.value.filter((b) => !b.isGameOver).some((b) => !b.goggles)) {
    isGameOver.value = true;
    currScore.value = 0;
    currSeconds.value = defaultSeconds;
    return;
  }
  currScore.value = Math.max(0, countScoring() - countDeduction());
  currSeconds.value = countSeconds();
};

const handleCancel = () => {
  // todo 取消
  resetData();
};
const handleSubmit = () => {
  if (!isScoring.value) {
    ElMessage.error("请先计分");
    return;
  }

  // todo 提交
  baseService
    .post("/front/spuser/saveScore", {
      id: queryForm.id,
      userId: contestInfo.value.userId,
      site: queryForm.site,
      score: currScore.value,
      seconds: currSeconds.value,
      matchItemTeamId: contestInfo.value.matchItemTeamId,
      add1: scoringData.value[0].throughHoops,
      add2: scoringData.value[0].anticlockwise,
      add3: scoringData.value[0].aroundDragonGate,
      add4: scoringData.value[0].highAndLowCircles,
      add5: scoringData.value[0].serpentineRing,
      add6: scoringData.value[0].parkingApron,
      sub1: deductionData.value[0].goggles,
      sub2: deductionData.value[0].touchNet,
      sub3: deductionData.value[0].touchPeople,
      sub4: deductionData.value[0].touchdown,
      sub5: deductionData.value[0].obstacles,
      sub6: deductionData.value[0].superelevation,
      sub7: deductionData.value[0].cross
    })
    .then((res) => {
      if (res.code === 0) {
        ElMessage.success("保存成功");
      }
    });
  resetData();
};

const GetRequest = (value: any) => {
  var url = decodeURI(window.location.search);
  debugger;
  var object = {} as any;
  if (url.indexOf("?") != -1) {
    var str = url.substr(1);
    var strs = str.split("&");
    for (var i = 0; i < strs.length; i++) {
      object[strs[i].split("=")[0]] = strs[i].split("=")[1]; //得到{id:'123456',name:'www'}
    }
  }
  return object[value];
};

const handleSetFull = () => {
  setScoring("full");
  handleScoring();
};
const handleSetZero = () => {
  setScoring("zero");
  handleScoring();
};

const getScoringColumnMap = () => {
  let map = new Map<string, number>();
  scoringColumn.forEach((b) => {
    map.set(b.prop, b.score || 0);
  });
  return map;
};

const getDeductionColumnMap = () => {
  let map = new Map<string, number>();
  deductionColumn.forEach((b) => {
    map.set(b.prop, b.score || 0);
  });
  return map;
};

const countScoring = () => {
  return scoringData.value.reduce((prev: number, cur: any) => {
    return (
      prev +
      Object.keys(cur).reduce((scoringPrev, scoringKey: string) => {
        if (scoringKey == "parkingApron") {
          return scoringPrev + (cur[scoringKey] || 0);
        } else if (cur[scoringKey]) {
          return scoringPrev + (scoringColumnMap.value.get(scoringKey) || 0);
        } else {
          return scoringPrev;
        }
      }, 0)
    );
  }, 0);
};
const countDeduction = () => {
  return deductionData.value
    .filter((b) => !b.isGameOver)
    .reduce((prev: number, cur: any) => {
      let total = Object.keys(cur).reduce((scoringPrev, scoringKey: string) => {
        if (scoringKey == "goggles") {
          return scoringPrev;
        } else {
          return scoringPrev + (deductionColumnMap.value.get(scoringKey) || 0) * (cur[scoringKey] || 0);
        }
      }, 0);
      return prev + total;
    }, 0);
};
const countSeconds = () => {
  const { minute, second, millisecond } = secondsItem.value;
  let integerSecond = (minute || 0) * 60 + (second || 0);
  if (integerSecond + millisecond / 1000 > maxSeconds) {
    return defaultSeconds;
  }
  return `${Math.min(maxSeconds, integerSecond)}″${String(millisecond || 0)
    .slice(0, 2)
    .padEnd(2, "0")}`;
};

const resetData = () => {
  scoringData.value = [
    {
      throughHoops: null,
      anticlockwise: null,
      aroundDragonGate: null,
      highAndLowCircles: null,
      serpentineRing: null,
      parkingApron: null
    }
  ];
  deductionData.value = [
    {
      isGameOver: null,
      goggles: true,
      touchNet: 0,
      touchPeople: 0,
      touchdown: 0,
      obstacles: 0,
      superelevation: 0,
      cross: 0
    }
  ];
  secondsItem.value = {
    minute: 2,
    second: 0,
    millisecond: 0
  };
  isScoring.value = false;
  isGameOver.value = false;
  currScore.value = 0;
  currSeconds.value = defaultSeconds;
};

const setScoring = (type = "reset") => {
  scoringData.value.forEach((scoringItem, scoringIdx) => {
    Object.keys(scoringItem).forEach((key) => {
      if (key == "parkingApron") {
        (scoringData.value[scoringIdx] as any)[key] = type === "full" ? Math.max(...parkingApronOpts.value.map((b) => b.value)) : null;
      } else {
        (scoringData.value[scoringIdx] as any)[key] = type === "full" ? true : type === "zero" ? false : null;
      }
    });
  });
};

const deductionSpanMethod = ({ row, column, rowIndex, columnIndex }: { row: any; column: any; rowIndex: number; columnIndex: number }) => {
  if (!row.isGameOver) return;
  return {
    rowspan: 1,
    colspan: columnIndex ? 0 : 7
  };
};
const deductionRowClass = ({ row }: { row: any }) => {
  return row.isGameOver ? "tr-end" : "";
};
</script>

<style scoped>
.scoring-module {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.header {
  width: 1200px;
  height: 50px;
  display: flex;
  justify-content: space-between;
  padding: 0 24px;
  box-sizing: border-box;
  align-items: center;
  background: #00a0e9;

  .title {
    color: #fff;
    font-weight: 500;
    font-size: 18px;
  }

  .ico-logo {
    width: 115px;
    height: 40px;
  }
}

.content {
  margin-top: 0px;
  width: 1200px;
  //min-height: 850px;
  padding: 0 24px;
  box-sizing: border-box;
  background: #fff;
  border-radius: 12px;
}

.flying-race-box {
  width: 1152px;
  height: 74px;
  padding: 14px 14px;
  box-sizing: border-box;
  display: flex;
  background: linear-gradient(90deg, #fbfbfb 0%, #eff6ff 100%);
  border-radius: 12px;
  .flying-race-logo-wrap {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #00a0e9;
    border-radius: 50%;
    .flying-race-logo {
      width: 30px;
      height: 30px;
      border-radius: 50%;
      overflow: hidden;
    }
  }
  .flying-race-info {
    margin-left: 16px;
    padding-top: 7px;
    .flying-race-title {
      color: #333;
      font-size: 18px;
      font-weight: 500;
      line-height: 22px;
    }
  }
  .flying-race-labels {
    margin-top: 10px;
    display: flex;
    align-items: center;
    .flying-race-label {
      color: #333;
      font-size: 16px;
      font-weight: 400;
      line-height: 22px;
      & + .flying-race-label {
        margin-left: 24px;
      }
    }
  }
  .flying-race-tags {
    margin-top: 6px;
    display: flex;
    align-items: center;
    .flying-race-tag {
      color: #00a0e9;
      font-size: 16px;
      font-weight: 400;
      line-height: 22px;
      & + .flying-race-tag {
        margin-left: 24px;
      }
    }
  }
}

.form-query-box {
  margin-top: 24px;
  display: flex;
  align-items: center;
}
.form-box {
  flex: 1;
  overflow: hidden;
  display: flex;
  align-items: center;
  .form-item {
    display: flex;
    align-items: center;
    & + .form-item {
      margin-left: 24px;
    }
    .form-item-label {
      font-weight: 400;
      font-size: 16px;
      color: #333;
      line-height: 22px;
    }
    .form-item-val {
      margin-left: 4px;
      width: 272px;
      height: 38px;
      :deep(.el-input__wrapper) {
        background-color: #fff !important;
      }
    }
  }
  .btn-query {
    margin-left: 18px;
    width: 68px;
    height: 38px;
    border-radius: 6px;
  }
  .btn-reset {
    margin-left: 12px;
    width: 68px;
    height: 38px;
    border-radius: 6px;
  }
}
.scoring-box {
  display: flex;
  align-items: center;
  .btn-scoring {
    width: 72px;
    height: 38px;
    border-radius: 6px;
  }
  .scoring-count {
    margin-left: 12px;
    width: 88px;
    height: 38px;
    display: flex;
    justify-content: center;
    align-items: center;
    background: #fff;
    border-radius: 6px;
    border: 1px solid rgba(0, 160, 233, 0.4);
    font-weight: 500;
    font-size: 20px;
    color: #333333;
    line-height: 28px;
    text-align: center;
  }
  .scoring-unit {
    margin-left: 8px;
    font-weight: 400;
    font-size: 16px;
    color: #4f5a70;
    line-height: 22px;
  }
}

.scoring-table-box {
  margin-top: 10px;
  .scoring-table-title {
    display: flex;
    align-items: center;
    font-weight: 500;
    font-size: 18px;
    color: #333333;
    line-height: 25px;
    &::before {
      content: "";
      margin-right: 8px;
      width: 4px;
      height: 12px;
      background: #00a0e9;
    }
  }
  .scoring-table-wrap {
    margin-top: 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  .scoring-table {
    width: 896px;
    border-radius: 8px;
    border: 1px solid #e4e7ec;
    :deep() {
      & th,
      & td {
        border-left: 1px solid #e4e7ec;
        height: 48px;
        &:first-child {
          border: none;
        }
      }
      .tr-end {
        height: 28px;
        background: rgba(253, 106, 110, 0.1);
        font-weight: 500;
        font-size: 14px;
        color: #fd6a6e;
        line-height: 20px;
        &:hover > td {
          background-color: transparent;
        }
        td {
          height: 28px;
          border: 1px solid rgba(253, 106, 110, 0.59);
          .cell {
            line-height: 1;
          }
        }
      }
    }
    .scoring-select {
      width: 90px;
      :deep(.el-select__wrapper) {
        box-shadow: none;
        .el-select__selected-item {
          text-align: center;
        }
      }
    }
    .scoring-ipt {
      :deep(.el-input__wrapper) {
        box-shadow: none;
        background: #fff !important;
        .el-input__inner {
          font-weight: 500;
          font-size: 16px;
          color: #00a0e9;
          line-height: 16px;
          text-align: center;
        }
      }
      &.scoring-ipt-wran {
        :deep(.el-input__wrapper) {
          .el-input__inner {
            color: #fd6a6e;
          }
        }
      }
    }
    .scoring-radio {
      flex-wrap: nowrap;
      .el-radio {
        margin-right: 16px;
      }
    }
  }
  .scoring-time-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 232px;
    height: 96px;
    background: #effaff;
    border-radius: 8px;
    border: 1px solid #dbf4ff;
    .time-label-wrap {
      display: flex;
      align-items: center;
      font-weight: 500;
      font-size: 16px;
      color: #333;
      line-height: 22px;
      .time-label {
        margin-right: 8px;
      }
      .time-count {
        color: #00a0e9;
      }
    }
    .timer-box {
      margin-top: 10px;
      display: flex;
      align-items: center;
      font-weight: 500;
      font-size: 16px;
      color: #333;
      line-height: 22px;
      .timer-item-ipt {
        width: 38px;
        height: 38px;
        :deep() {
          .el-input__wrapper {
            border-radius: 6px;
            background-color: #fff !important;
            &:not(.is-focus) {
              box-shadow: none !important;
            }
            .el-input__inner {
              text-align: center;
            }
          }
          input::-webkit-outer-spin-button,
          input::-webkit-inner-spin-button {
            -webkit-appearance: none;
          }
          input[type="number"] {
            -moz-appearance: textfield;
          }
        }
      }
      .timer-split {
        margin: 0 8px;
      }
    }
  }
}

.form-btns-box {
  margin-top: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  .form-btn {
    width: 88px;
    height: 38px;
    border-radius: 6px;
    & + .form-btn {
      margin-left: 16px;
    }
  }
  .btn-set-zero,
  .btn-set-full {
    color: #00a0e9;
    background: #fff;
    &:hover {
      color: #fff;
      background: #00a0e9;
    }
  }
}
</style>
